package com.ruoyi.smartai.service.impl;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.smartai.service.IReturnVisitService;
import com.ruoyi.smartai.utils.WhatsAPPUtils;
import com.ruoyi.system.domain.ChatLog;
import com.ruoyi.system.domain.FansInfo;
import com.ruoyi.system.domain.GeneralBase;
import com.ruoyi.system.domain.smartai.CurrentScenarioData;
import com.ruoyi.system.domain.smartai.ScenarioDataUtils;
import com.ruoyi.system.domain.smartai.SceneDetail;
import com.ruoyi.system.mapper.ChatLogMapper;
import com.ruoyi.system.mapper.FansInfoMapper;
import com.ruoyi.system.mapper.GeneralBaseMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * 回访
 */
@Service
public class ReturnVisitServiceImpl implements IReturnVisitService {

    private static final Logger log = LoggerFactory.getLogger(ReturnVisitServiceImpl.class);

    @Autowired(required = false)
    private ChatLogMapper chatLogMapper;

    @Autowired(required = false)
    private FansInfoMapper fansInfoMapper;

    @Autowired(required = false)
    private GeneralBaseMapper generalBaseMapper;

    @Autowired(required = false)
    RedisCache redisCache;

    @Value("${apiSevicePath.secketSendmessage}")
    private String newChatURL;

    /**
     * 获取回访状态
     */
    @Override
    public Map<String, Object> getReturnVisitStatus(String clientNumber) {
        String key = "return_visit:" + clientNumber;
        Map<String, Object> status = redisCache.getCacheMap(key);
        // 如果 status 为 null 或为空，则初始化默认值
        if (status == null || status.isEmpty()) {
            status = createDefaultStatus();
        }
        return status;
    }

    /**
     * 创建默认的回访状态
     */
    @Override
    public Map<String, Object> createDefaultStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("count", 0);
        status.put("last_time", 0L);
        status.put("used_replies", new ArrayList<String>());
        return status;
    }

    /**
     * 更新回访状态
     */
    @Override
    public void updateReturnVisitStatus(String clientNumber, Map<String, Object> status) {
        String key = "return_visit:" + clientNumber;
        redisCache.setCacheMap(key, status);
    }


    /**
     * 智能回访，梯度回访，先是两个小时
     */
    @Scheduled(fixedRate = 2 * 60 * 60 * 1000, initialDelay = 10 * 60 * 1000)
    public void returnVisit() {
        String isOpen = redisCache.getCacheObject("Scheduled:open");
        if ("1".equals(isOpen)) {
            return;
        }
        redisCache.keys("persona:scenario:fans:*")
                .parallelStream()
                .map(key -> redisCache.getCacheObject(key, CurrentScenarioData.class))
                .filter(Objects::nonNull)
                .forEach(data -> {
                    try {
                        // 分别检查是否需要开启下一个场景或下一天
                        if (isReadyForNextScenario(data)) {
                            log.info("Starting next scenario for user {}", data.getScenarioName());
                            startNextScenario(data);
                        } else if (isReadyForNextDay(data)) {
                            log.info("Starting next day for user {}", data.getScenarioName());
                            startNextDay(data);
                        } else {
                            contentReturnVisit();
                        }
                    } catch (Exception e) {
                        log.error("Error processing scenario {}: {}", data.getScenarioName(), e.getMessage(), e);
                    }
                });


        log.info("开始执行回访功能");
    }

    private void contentReturnVisit() {
        CompletableFuture.runAsync(() -> {
            // 获取 2 小时前的聊天记录
            List<ChatLog> chatLogs = chatLogMapper.selectChatByCreateTime();
            chatLogs.stream().forEach(chatLog -> {
                try {
                    String isWorkKeys = "persona:customer:" + chatLog.getCustomerNumber() + ":work";
                    Integer isWork = redisCache.getCacheObject(isWorkKeys);
                    if (isWork != null) {
                        if (isWork == 1) {
                            log.warn("现在是休息时间，暂停回复");
                            return;
                        }
                    }
                } catch (Exception e) {
                    log.warn("Exception，暂停回复:" + e);
                }
                String clientNumber = chatLog.getClientNumber();
                String keys = "persona:fans:" + clientNumber + ":statics";
                String fansStatic = redisCache.getCacheObject(keys);
                if (StringUtils.isNull(fansStatic) || "1".equals(fansStatic)) {
                    return;
                }
                try {
                    Map<String, Object> status = getReturnVisitStatus(clientNumber);
                    int count = (int) status.get("count");
                    long lastTime = (long) status.get("last_time");
                    List<String> usedReplies = (List<String>) status.get("used_replies");
                    // 检查是否需要回访
                    long currentTime = System.currentTimeMillis();
                    long interval = getInterval(count);
                    if (currentTime - lastTime < interval) {
                        return; // 未达到间隔时间，跳过
                    }

                    int replyId = chatLog.getUserType().equals("0") ? 301 : 302; // userType=0 是客服，userType=1 是客户
                    // 获取未使用的回复内容
                    List<GeneralBase> replies = generalBaseMapper.selectUnusedReplies(usedReplies, replyId);
                    if (replies.isEmpty()) {
                        return; // 所有内容已使用完，跳过
                    }
                    // 选择一条回复内容
                    GeneralBase reply = replies.get(0);
                    usedReplies.add(reply.getId());
                    // 根据 userType 选择回复类型
                    String replyContent = reply.getReplyContent();
                    // 更新回访状态
                    status.put("count", count + 1);
                    status.put("last_time", currentTime);
                    status.put("used_replies", usedReplies);
                    updateReturnVisitStatus(clientNumber, status);
                    // 执行回访（例如调用发送消息的接口）
//                sendReply(clientNumber, replyId, replyContent);
                    if (replyContent.contains("&")) {
                        String[] mesaage = replyContent.split("&");
                        for (String mes : mesaage) {
                            WhatsAPPUtils.sendMessage(newChatURL, chatLog.getCustomerNumber(), clientNumber, "0",
                                    mes, "1", true);
                        }
                    }
                } catch (Exception e) {
                    log.error("returnVisit Exception:" + e);
                }
            });
        });
    }


    private boolean isReadyForNextScenario(CurrentScenarioData data) {
        try {

            long currentTimeMillis = System.currentTimeMillis();

            // 将Date转换为时间戳
            long lastReplyTime = data.getCurrentTime().getTime();
            long scenarioStartTime = data.getScenarioTime().getTime();

            // 计算时间差
            long minutesSinceLastReply = TimeUnit.MILLISECONDS.toMinutes(
                    currentTimeMillis - lastReplyTime
            );
            long hoursSinceStart = TimeUnit.MILLISECONDS.toHours(
                    currentTimeMillis - scenarioStartTime
            );

            String dateTime = redisCache.getCacheObject("message:content:datetime");
            if (StringUtils.isEmpty(dateTime)) {
                dateTime = "0";
                redisCache.setCacheObject("message:content:datetime", dateTime);

            }
            return minutesSinceLastReply >= data.getNextTime() && hoursSinceStart < Integer.valueOf(dateTime);

        } catch (Exception e) {
            return false;
        }
    }

    private void startNextScenario(CurrentScenarioData data) {
        // 处理启动下个场景的逻辑
        SceneDetail sceneDetail = ScenarioDataUtils.startNextScenario(data);
        FansInfo fansInfo = fansInfoMapper.selectChatByClientNumber(data.getFansId());
        sendMessages(sceneDetail, fansInfo);
    }

    /**
     * 检查是否可以开始下一天
     */
    private boolean isReadyForNextDay(CurrentScenarioData data) {
        try {
            ZoneId beijingZone = ZoneId.of("Asia/Shanghai");
            LocalDateTime now = LocalDateTime.now(beijingZone);

            LocalDateTime scenarioStartTime = data.getScenarioTime()
                    .toInstant()
                    .atZone(beijingZone)
                    .toLocalDateTime();

            // 计算当天场景开始到现在的小时数
            long hoursSinceStart = ChronoUnit.HOURS.between(scenarioStartTime, now);
            String dateTime = redisCache.getCacheObject("message:content:datetime");
            if (StringUtils.isEmpty(dateTime)) {
                dateTime = "23";
                redisCache.setCacheObject("message:content:datetime", dateTime);

            }
            // 判断是否超过23小时且是最后一个场景
            return hoursSinceStart >= Integer.valueOf(dateTime);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 开始下一天
     */
    private void startNextDay(CurrentScenarioData data) {
        try {
            log.info("Successfully started next day for user {}", data.getScenarioName());
        } catch (Exception e) {
            log.error("Failed to start next day: {}", e.getMessage(), e);
        }
    }


    /**
     * 获取回访间隔时间
     */
    @Override
    public long getInterval(int count) {
        if (count == 0) return 0; // 第一次直接回复
        if (count == 1) return 3 * 60 * 60 * 1000; // 第二次间隔 3 小时
        if (count == 2) return 4 * 60 * 60 * 1000; // 第三次间隔 4 小时
        if (count == 3) return 5 * 60 * 60 * 1000; // 第四次间隔 5 小时
        return (count + 2) * 60 * 60 * 1000; // 第 5 次及以后，每次增加 1 小时
    }

    private void sendMessages(SceneDetail sceneDetail, FansInfo fansInfo) {
        CompletableFuture.runAsync(() -> {
            try {
                String content = sceneDetail.getContent();
                if (StringUtils.isNotEmpty(fansInfo.getClientName())) {
                    content = content.replace("{fansName}", fansInfo.getClientName());
                }
                String meageData = WhatsAPPUtils.sendMessage(newChatURL, fansInfo.getCustomerNumber(), fansInfo.getClientNumber(), "0", content, "0", true);
                log.info(fansInfo.getCustomerNumber() + " to " + fansInfo.getClientNumber() + " 发送消息：" + sceneDetail.getContent() + " is " + meageData);
                // 获取延时时间（单位：秒）
                String delayTime = "3";
                if (delayTime == null) {
                    delayTime = "5";  // 如果未设置，默认为5秒
                }

                WhatsAPPUtils.randomThread(5, Integer.valueOf(delayTime));
                String keys = "persona:fans:" + fansInfo.getClientNumber() + ":statics";
                redisCache.setCacheObject(keys, "0");

                if (sceneDetail.getImages() != null) {
                    if (sceneDetail.getImages().size() != 0) {
                        for (int i = 0; i < sceneDetail.getImages().size(); i++) {
                            String imageData = WhatsAPPUtils.sendMessage(newChatURL, fansInfo.getCustomerNumber(), fansInfo.getClientNumber(), "1", sceneDetail.getImages().get(i), i + "", false);
                            log.info(fansInfo.getCustomerNumber() + " to " + fansInfo.getClientNumber() + " 发送图片：" + imageData);
                            WhatsAPPUtils.randomThread(3, Integer.valueOf(5));
                        }
                    }
                }
                String currentKey = ScenarioDataUtils.SCENARIO_FANS_KEY_PREFIX + fansInfo.getClientNumber();
                CurrentScenarioData currentScenarioData = redisCache.getCacheObject(currentKey);
                fansInfo.setStepId(currentScenarioData.getCurrentRounds() + "");
                fansInfo.setDaysNumber(currentScenarioData.getCurrentDayNo() + "");
                fansInfo.setScenesId(currentScenarioData.getScenarioName() + "");
                fansInfoMapper.updateDaysNumberByClientNumber(fansInfo);
            } catch (Exception e) {
                log.error("异步执行对话任务失败: " + e.getMessage(), e);
            }
        });
    }
}
